import Common from './common'
import Utils from './utils'

const THROTTLE_DELAY_TIME = 30
const MINIMUM_SIZE = 4
const ROTATE_CURSOR_DIFF = 13
const LINE_WIDTH = 13
let staticValueDefault = {
  negativeThirty: -25,
  four: 6,
  two: 2,
  lineWidth: 13,
  rotate: 20,
}

function hasTouch () {
  // let touchObj = {}
  // touchObj.isSupportTouch = 'ontouchend' in document ? true : false
  // touchObj.isEvent = touchObj.isSupportTouch ? 'touchstart' : 'click'
  // return touchObj.isEvent
  return /(Android|iPhone|SymbianOS|Windows Phone|iPad|iPod)/ig.test(navigator.userAgent) || 'ontouchend' in document
}

if (window.innerWidth < 500 || hasTouch()) {
  staticValueDefault.negativeThirty *= 1.2
  staticValueDefault.two *= 1.8
  staticValueDefault.four *= 1.5
  staticValueDefault.lineWidth *= 1.2
  staticValueDefault.rotate *= 1.5
}

const SettingCursor = (rotate, position) => {
  console.log(this, position)
  let point
  // switch (position) {
  //   case 'top-left':
  //     point = {
  //       x: rect.x,
  //       y: rect.y
  //     }
  //     return Common.getRotatedPoint(point, center, rect.rotate)
  //   case 'top-middle':
  //     point = {
  //       x: rect.x + (rect.width / 2),
  //       y: rect.y
  //     }
  //     return Common.getRotatedPoint(point, center, rect.rotate)
  //   case 'top-right':
  //     point = {
  //       x: rect.x + rect.width,
  //       y: rect.y
  //     }
  //     return Common.getRotatedPoint(point, center, rect.rotate)
  //   case 'bottom-left':
  //     point = {
  //       x: rect.x,
  //       y: rect.y + rect.height
  //     }
  //     return Common.getRotatedPoint(point, center, rect.rotate)
  //   case 'bottom-middle':
  //     point = {
  //       x: rect.x + (rect.width / 2),
  //       y: rect.y + rect.height
  //     }
  //     return Common.getRotatedPoint(point, center, rect.rotate)
  //   case 'bottom-right':
  //     point = {
  //       x: rect.x + rect.width,
  //       y: rect.y + rect.height
  //     }
  //     return Common.getRotatedPoint(point, center, rect.rotate)
  //   case 'middle-left':
  //     point = {
  //       x: rect.x,
  //       y: rect.y + (rect.height / 2)
  //     }
  //     return Common.getRotatedPoint(point, center, rect.rotate)
  //   case 'middle-right':
  //     point = {
  //       x: rect.x + rect.width,
  //       y: rect.y + (rect.height / 2)
  //     }
  //     return Common.getRotatedPoint(point, center, rect.rotate)
  //   default:
  //     point = {x: rect.x, y: rect.y}
  //     return Common.getRotatedPoint(point, center, rect.rotate)
// }
}

/**
 * 重置大小
 * @returns {{x: number, y: number, width: number, height: number, rotate: number}}
 */
const resetSize = () => ({
  x: 0,
  y: 0,
  width: 0,
  height: 0,
  rotate: 0
})

/**
 * 获取旋转后的手柄坐标
 * @param  {Object} rect     形状的宽高坐标
 * @param  {Object} center   旋转中心的坐标
 * @param  {String} position 手柄名称
 * @return {Object}          旋转后的手柄坐标
 */
const getPoint = (rect, center, position) => {
  let point

  switch (position) {
    case 'top-left':
      point = {
        x: rect.x,
        y: rect.y
      }
      return Common.getRotatedPoint(point, center, rect.rotate)
    case 'top-middle':
      point = {
        x: rect.x + (rect.width / 2),
        y: rect.y
      }
      return Common.getRotatedPoint(point, center, rect.rotate)
    case 'top-right':
      point = {
        x: rect.x + rect.width,
        y: rect.y
      }
      return Common.getRotatedPoint(point, center, rect.rotate)
    case 'bottom-left':
      point = {
        x: rect.x,
        y: rect.y + rect.height
      }
      return Common.getRotatedPoint(point, center, rect.rotate)
    case 'bottom-middle':
      point = {
        x: rect.x + (rect.width / 2),
        y: rect.y + rect.height
      }
      return Common.getRotatedPoint(point, center, rect.rotate)
    case 'bottom-right':
      point = {
        x: rect.x + rect.width,
        y: rect.y + rect.height
      }
      return Common.getRotatedPoint(point, center, rect.rotate)
    case 'middle-left':
      point = {
        x: rect.x,
        y: rect.y + (rect.height / 2)
      }
      return Common.getRotatedPoint(point, center, rect.rotate)
    case 'middle-right':
      point = {
        x: rect.x + rect.width,
        y: rect.y + (rect.height / 2)
      }
      return Common.getRotatedPoint(point, center, rect.rotate)
    default:
      point = {x: rect.x, y: rect.y}
      return Common.getRotatedPoint(point, center, rect.rotate)
  }
}

/**
 * 获取两点之间连线后的中点坐标
 * @param  {Object} p1 点1的坐标
 * @param  {Object} p2 点2的坐标
 * @return {Object}    中点坐标
 */
const getCenterPoint = (p1, p2) => ({
  x: p1.x + ((p2.x - p1.x) / 2),
  y: p1.y + ((p2.y - p1.y) / 2)
})

/**
 * 检测 p0 是否在 p1 与 p2 建立的矩形内
 * @param  {Object}  p0 被检测的坐标
 * @param  {Object}  p1 点1坐标
 * @param  {Object}  p2 点2坐标
 * @return {Boolean}    检测结果
 */
const pointInRect = (p0, p1, p2) => {
  if (p1.x > p2.x) {
    if (p0.x < p2.x) {
      return false
    }
  } else {
    if (p0.x > p2.x) {
      return false
    }
  }

  if (p1.y > p2.y) {
    if (p0.y < p2.y) {
      return false
    }
  } else {
    if (p0.y > p2.y) {
      return false
    }
  }

  return true
}

/**
 * 获取关键变量（计算尺寸调整逻辑用）
 * @param  {String} handler 手柄名称
 * @return {Object}         关键变量集合
 */
const getKeyVariable = function (handler) {
  const viewportRef = this.getViewportRef()
  const rect = {
    x: this.current.x,
    y: this.current.y,
    width: this.current.width,
    height: this.current.height,
    rotate: this.current.rotate
  }
  const center = {
    x: rect.x + (rect.width / 2),
    y: rect.y + (rect.height / 2)
  }
  const handlePoint = getPoint(rect, center, handler)
  const sPoint = {
    x: center.x + Math.abs(handlePoint.x - center.x) * (handlePoint.x < center.x ? 1 : -1),
    y: center.y + Math.abs(handlePoint.y - center.y) * (handlePoint.y < center.y ? 1 : -1)
  }
  const proportion = this.workspace.lockProportions ? (rect.width / rect.height) : 1

  return {
    viewportRef,  // 页面SVG元素的引用（计算鼠标位置需要用到）
    rect,         // 元素原始几何信息（xy宽高）
    center,       // 元素原始中心点坐标
    handlePoint,  // 当前拖动手柄的虚拟坐标（旋转后的坐标）
    sPoint,       // 拖动手柄的对称点的坐标（假设拖动的是左上角手柄，那么他的对称点就是右下角的点）
    proportion    // 宽高比
  }
}
/**
 * 处理方法
 * @type {{dragElement(*=): void, eventRegister(*=, *): void, dragRotateHandle(*): void, dragTopLeftHandle(*): void, dragTopMiddleHandle(*): void, dragTopRightHandle(*): void, dragBottomLeftHandle(*): void, dragBottomMiddleHandle(*): void, dragBottomRightHandle(*): void, dragMiddleLeftHandle(*): void, dragMiddleRightHandle(*): void}}
 */
const handleMethods = {
  /**
   * 活动登记
   * @param mousemoveHandler
   * @param e
   */
  eventRegister (mousemoveHandler, e) {
    let that = this
    const isTouchMove = e.type.indexOf('touch') !== -1
    that.isShowLine = true
    this.$emit('press', that.id, 'press', that.current)
    const mouseupHandler = (ev) => {
      this.$emit('loosen', that.id, 'loosen', that.current)
      if (!isTouchMove) {
        window.removeEventListener('mousemove', mousemoveHandler)
        window.removeEventListener('mouseup', mouseupHandler)
      } else {
        window.removeEventListener('touchmove', mousemoveHandler)
        window.removeEventListener('touchend', mouseupHandler)
      }
      that.isShowLine = false
      // document.documentElement.removeEventListener('mousemove', mousemoveHandler)
      // document.documentElement.removeEventListener('mouseup', mouseupHandler)
      // touch events bindings removed
      // document.documentElement.removeEventListener('touchmove', mousemoveHandler)
      // document.documentElement.removeEventListener('touchend touchcancel', mouseupHandler)
    }
    if (!isTouchMove) {
      window.addEventListener('mousemove', mousemoveHandler)
      window.addEventListener('mouseup', mouseupHandler)
    } else {
      window.addEventListener('touchmove', mousemoveHandler)
      window.addEventListener('touchend', mouseupHandler)
    }
    // document.documentElement.addEventListener('mousemove', mousemoveHandler)
    // document.documentElement.addEventListener('mouseup', mouseupHandler)
    // touch events bindings removed
    // document.documentElement.addEventListener('touchmove', mousemoveHandler)
    // document.documentElement.addEventListener('touchend touchcancel', mouseupHandler)
  },
  /**
   * 拖动元素
   */
  dragElement (e) {
    const target = e.target || e.srcElement
    let draged = false
    const viewportRef = this.getViewportRef()
    const mouseDownPosition = Common.getPositionInSvg(viewportRef, e)
    const originPosition = {
      x: this.current.x,
      y: this.current.y
    }
    let i = 0
    console.log(e.type, i, mouseDownPosition, this.current.x, this.current.y)
    const dragMoveHandler = e => {
      draged = true
      const currentPosition = Common.getPositionInSvg(viewportRef, e)
      let newPosition = {
        x: originPosition.x + currentPosition.x - mouseDownPosition.x,
        y: originPosition.y + currentPosition.y - mouseDownPosition.y
      }
      Object.assign(this.current, {
        x: newPosition.x,
        y: newPosition.y,
      })
      console.log(e.type, i, currentPosition, this.current.x, this.current.y, newPosition)
      this.$emit('changing', this.id, 'move', this.current)
    }

    const mousemoveHandler = Utils.throttle(dragMoveHandler, THROTTLE_DELAY_TIME, true)

    this.eventRegister(mousemoveHandler, e)
  },
  /**
   * 拖动旋转手柄
   * @param e
   */
  dragRotateHandle (e) {
    let draged = false
    const viewportRef = this.getViewportRef()
    const rect = {
      x: this.current.x,
      y: this.current.y,
      width: this.current.width,
      height: this.current.height,
      rotate: this.current.rotate
    }

    const originCenter = {
      x: rect.x + (rect.width / 2),
      y: rect.y + (rect.height / 2)
    }

    const mousemoveHandler = Utils.throttle(e => {
      draged = true
      const currentPosition = Common.getPositionInSvg(viewportRef, e)

      const a = Math.abs(currentPosition.x - originCenter.x)
      const b = Math.abs(currentPosition.y - originCenter.y)
      const c = Math.sqrt(a * a + b * b)
      let rotate = Math.round((Math.asin(b / c) / Math.PI * 180))

      // 第一象限
      if (currentPosition.x >= originCenter.x && currentPosition.y <= originCenter.y) {
        rotate = 90 - rotate
      }
      // 第二象限
      else if (currentPosition.x <= originCenter.x && currentPosition.y <= originCenter.y) {
        rotate = 270 + rotate
      }
      // 第三象限
      else if (currentPosition.x <= originCenter.x && currentPosition.y >= originCenter.y) {
        rotate = 270 - rotate
      }
      // 第四象限
      else if (currentPosition.x >= originCenter.x && currentPosition.y >= originCenter.y) {
        rotate = 90 + rotate
      }

      this.current.rotate = rotate === 360 ? 0 : parseInt(rotate)
    }, THROTTLE_DELAY_TIME, true)

    this.eventRegister(mousemoveHandler, e)
  },
  /**
   * 拖动左上手柄
   * @param e
   */
  dragTopLeftHandle (e) {
    let draged = false
    const {viewportRef, sPoint, rect, proportion} = getKeyVariable.call(this, 'top-left')
    const mousemoveHandler = Utils.throttle(e => {
      draged = true

      let currentPosition = Common.getPositionInSvg(viewportRef, e)
      let newCenterPoint = getCenterPoint(currentPosition, sPoint)
      let newTopLeftPoint = Common.getRotatedPoint(currentPosition, newCenterPoint, -rect.rotate)
      let newBottomRightPoint = Common.getRotatedPoint(sPoint, newCenterPoint, -rect.rotate)

      let newWidth = newBottomRightPoint.x - newTopLeftPoint.x
      let newHeight = newBottomRightPoint.y - newTopLeftPoint.y

      if (this.workspace.lockProportions) {
        if (newWidth / newHeight > proportion) {
          newTopLeftPoint.x = newTopLeftPoint.x + Math.abs(newWidth - newHeight * proportion)
          newWidth = newHeight * proportion
        } else {
          newTopLeftPoint.y = newTopLeftPoint.y + Math.abs(newHeight - newWidth / proportion)
          newHeight = newWidth / proportion
        }

        let rotatedTopLeftPoint = Common.getRotatedPoint(newTopLeftPoint, newCenterPoint, rect.rotate)
        newCenterPoint = getCenterPoint(rotatedTopLeftPoint, sPoint)
        newTopLeftPoint = Common.getRotatedPoint(rotatedTopLeftPoint, newCenterPoint, -rect.rotate)
        newBottomRightPoint = Common.getRotatedPoint(sPoint, newCenterPoint, -rect.rotate)

        newWidth = newBottomRightPoint.x - newTopLeftPoint.x
        newHeight = newBottomRightPoint.y - newTopLeftPoint.y
      }

      if (newWidth < MINIMUM_SIZE || (newHeight < MINIMUM_SIZE)) {
        return
      }

      Object.assign(this.current, {
        x: newTopLeftPoint.x,
        y: newTopLeftPoint.y,
        height: newHeight,
        width: newWidth
      })

      this.$emit('changing', this.id, 'top-left', this.current, newTopLeftPoint)
    }, THROTTLE_DELAY_TIME, true)
    this.eventRegister(mousemoveHandler, e)
  },
  /**
   * 拖动顶部中间把手
   * @param e
   */
  dragTopMiddleHandle (e) {
    let draged = false
    const {rect, viewportRef, sPoint, handlePoint} = getKeyVariable.call(this, 'top-middle')

    const mousemoveHandler = Utils.throttle(e => {
      draged = true
      const currentPosition = Common.getPositionInSvg(viewportRef, e)

      const rotatedCurrentPosition = Common.getRotatedPoint(currentPosition, handlePoint, -rect.rotate)
      const rotatedTopMiddlePoint = Common.getRotatedPoint({
        x: handlePoint.x,
        y: rotatedCurrentPosition.y
      }, handlePoint, rect.rotate)

      const newHeight = Math.sqrt(Math.pow(rotatedTopMiddlePoint.x - sPoint.x, 2) + Math.pow(rotatedTopMiddlePoint.y - sPoint.y, 2), 2)
      const newCenter = {
        x: rotatedTopMiddlePoint.x - (Math.abs(sPoint.x - rotatedTopMiddlePoint.x) / 2) * (rotatedTopMiddlePoint.x > sPoint.x ? 1 : -1),
        y: rotatedTopMiddlePoint.y + (Math.abs(sPoint.y - rotatedTopMiddlePoint.y) / 2) * (rotatedTopMiddlePoint.y > sPoint.y ? -1 : 1)
      }

      if (newHeight < MINIMUM_SIZE) {
        return
      }

      if (!pointInRect(newCenter, handlePoint, sPoint)) {
        return
      }

      Object.assign(this.current, {
        height: newHeight,
        y: newCenter.y - (newHeight / 2),
        x: newCenter.x - (rect.width / 2)
      })

      this.$emit('changing', this.id, 'top-middle', this.current, rotatedTopMiddlePoint, currentPosition)
    }, THROTTLE_DELAY_TIME, true)

    this.eventRegister(mousemoveHandler, e)
  },
  /**
   * 拖动右上角
   * @param e
   */
  dragTopRightHandle (e) {
    let draged = false
    const {viewportRef, sPoint, rect, proportion} = getKeyVariable.call(this, 'top-right')

    const mousemoveHandler = Utils.throttle(e => {
      draged = true
      let currentPosition = Common.getPositionInSvg(viewportRef, e)
      let newCenterPoint = getCenterPoint(currentPosition, sPoint)

      let newTopRightPoint = Common.getRotatedPoint(currentPosition, newCenterPoint, -rect.rotate)
      let newBottomLeftPoint = Common.getRotatedPoint(sPoint, newCenterPoint, -rect.rotate)

      let newWidth = newTopRightPoint.x - newBottomLeftPoint.x
      let newHeight = newBottomLeftPoint.y - newTopRightPoint.y

      if (this.workspace.lockProportions) {
        if (newWidth / newHeight > proportion) {
          newTopRightPoint.x = newTopRightPoint.x - Math.abs(newWidth - newHeight * proportion)
          newWidth = newHeight * proportion
        } else {
          newTopRightPoint.y = newTopRightPoint.y + Math.abs(newHeight - newWidth / proportion)
          newHeight = newWidth / proportion
        }

        let rotatedTopRightPoint = Common.getRotatedPoint(newTopRightPoint, newCenterPoint, rect.rotate)
        newCenterPoint = getCenterPoint(rotatedTopRightPoint, sPoint)
        newTopRightPoint = Common.getRotatedPoint(rotatedTopRightPoint, newCenterPoint, -rect.rotate)
        newBottomLeftPoint = Common.getRotatedPoint(sPoint, newCenterPoint, -rect.rotate)

        newWidth = newTopRightPoint.x - newBottomLeftPoint.x
        newHeight = newBottomLeftPoint.y - newTopRightPoint.y
      }

      if (newWidth < MINIMUM_SIZE || (newHeight < MINIMUM_SIZE)) {
        return
      }

      Object.assign(this.current, {
        x: newBottomLeftPoint.x,
        y: newTopRightPoint.y,
        height: newHeight,
        width: newWidth
      })
      this.$emit('changing', this.id, 'top-right', this.current, newTopRightPoint, currentPosition)
    }, THROTTLE_DELAY_TIME, true)

    this.eventRegister(mousemoveHandler, e)
  },
  /**
   * 拖动左下手柄
   * @param e
   */
  dragBottomLeftHandle (e) {
    let draged = false
    const {viewportRef, sPoint, rect, proportion} = getKeyVariable.call(this, 'bottom-left')

    const mousemoveHandler = Utils.throttle(e => {
      draged = true
      let currentPosition = Common.getPositionInSvg(viewportRef, e)
      let newCenterPoint = getCenterPoint(currentPosition, sPoint)

      let newTopRightPoint = Common.getRotatedPoint(sPoint, newCenterPoint, -rect.rotate)
      let newBottomLeftPoint = Common.getRotatedPoint(currentPosition, newCenterPoint, -rect.rotate)

      let newWidth = newTopRightPoint.x - newBottomLeftPoint.x
      let newHeight = newBottomLeftPoint.y - newTopRightPoint.y

      if (this.workspace.lockProportions) {
        if (newWidth / newHeight > proportion) {
          newBottomLeftPoint.x = newBottomLeftPoint.x + Math.abs(newWidth - newHeight * proportion)
          newWidth = newHeight * proportion
        } else {
          newBottomLeftPoint.y = newBottomLeftPoint.y - Math.abs(newHeight - newWidth / proportion)
          newHeight = newWidth / proportion
        }

        let rotatedBottomLeftPoint = Common.getRotatedPoint(newBottomLeftPoint, newCenterPoint, rect.rotate)
        newCenterPoint = getCenterPoint(rotatedBottomLeftPoint, sPoint)
        newBottomLeftPoint = Common.getRotatedPoint(rotatedBottomLeftPoint, newCenterPoint, -rect.rotate)
        newTopRightPoint = Common.getRotatedPoint(sPoint, newCenterPoint, -rect.rotate)

        newWidth = newTopRightPoint.x - newBottomLeftPoint.x
        newHeight = newBottomLeftPoint.y - newTopRightPoint.y
      }

      if (newWidth < MINIMUM_SIZE || (newHeight < MINIMUM_SIZE)) {
        return
      }

      Object.assign(this.current, {
        x: newBottomLeftPoint.x,
        y: newTopRightPoint.y,
        height: newHeight,
        width: newWidth
      })

      this.$emit('changing', this.id, 'bottom-left', this.current, newBottomLeftPoint)
    }, THROTTLE_DELAY_TIME, true)

    this.eventRegister(mousemoveHandler, e)
  },
  /**
   * 拖动底部中间手柄
   * @param e
   */
  dragBottomMiddleHandle (e) {
    let draged = false
    const {rect, viewportRef, sPoint, handlePoint} = getKeyVariable.call(this, 'bottom-middle')

    const mousemoveHandler = Utils.throttle(e => {
      draged = true
      const currentPosition = Common.getPositionInSvg(viewportRef, e)

      const rotatedCurrentPosition = Common.getRotatedPoint(currentPosition, handlePoint, -rect.rotate)
      const rotatedBottomMiddlePoint = Common.getRotatedPoint({
        x: handlePoint.x,
        y: rotatedCurrentPosition.y
      }, handlePoint, rect.rotate)

      const newHeight = Math.sqrt(Math.pow(rotatedBottomMiddlePoint.x - sPoint.x, 2) + Math.pow(rotatedBottomMiddlePoint.y - sPoint.y, 2), 2)
      const newCenter = {
        x: rotatedBottomMiddlePoint.x - (Math.abs(sPoint.x - rotatedBottomMiddlePoint.x) / 2) * (rotatedBottomMiddlePoint.x > sPoint.x ? 1 : -1),
        y: rotatedBottomMiddlePoint.y + (Math.abs(sPoint.y - rotatedBottomMiddlePoint.y) / 2) * (rotatedBottomMiddlePoint.y > sPoint.y ? -1 : 1)
      }

      if (newHeight < MINIMUM_SIZE) {
        return
      }

      if (!pointInRect(newCenter, handlePoint, sPoint)) {
        return
      }

      Object.assign(this.current, {
        height: newHeight,
        y: newCenter.y - (newHeight / 2),
        x: newCenter.x - (rect.width / 2)
      })

      this.$emit('changing', this.id, 'bottom-middle', this.current, rotatedBottomMiddlePoint, currentPosition)
    }, THROTTLE_DELAY_TIME, true)

    this.eventRegister(mousemoveHandler, e)
  },
  /**
   * 拖动右手柄
   * @param e
   */
  dragBottomRightHandle (e) {
    let draged = false
    const {viewportRef, sPoint, rect, proportion} = getKeyVariable.call(this, 'bottom-right')

    const mousemoveHandler = Utils.throttle(e => {
      draged = true
      let currentPosition = Common.getPositionInSvg(viewportRef, e)
      let newCenterPoint = getCenterPoint(currentPosition, sPoint)

      let newTopLeftPoint = Common.getRotatedPoint(sPoint, newCenterPoint, -rect.rotate)
      let newBottomRightPoint = Common.getRotatedPoint(currentPosition, newCenterPoint, -rect.rotate)

      let newWidth = newBottomRightPoint.x - newTopLeftPoint.x
      let newHeight = newBottomRightPoint.y - newTopLeftPoint.y

      if (this.workspace.lockProportions) {
        if (newWidth / newHeight > proportion) {
          newBottomRightPoint.x = newBottomRightPoint.x - Math.abs(newWidth - newHeight * proportion)
          newWidth = newHeight * proportion
        } else {
          newBottomRightPoint.y = newBottomRightPoint.y - Math.abs(newHeight - newWidth / proportion)
          newHeight = newWidth / proportion
        }

        let rotatedBottomRightPoint = Common.getRotatedPoint(newBottomRightPoint, newCenterPoint, rect.rotate)
        newCenterPoint = getCenterPoint(rotatedBottomRightPoint, sPoint)
        newBottomRightPoint = Common.getRotatedPoint(rotatedBottomRightPoint, newCenterPoint, -rect.rotate)
        newTopLeftPoint = Common.getRotatedPoint(sPoint, newCenterPoint, -rect.rotate)

        newWidth = newBottomRightPoint.x - newTopLeftPoint.x
        newHeight = newBottomRightPoint.y - newTopLeftPoint.y
      }

      if (newWidth < MINIMUM_SIZE || (newHeight < MINIMUM_SIZE)) {
        return
      }

      Object.assign(this.current, {
        x: newTopLeftPoint.x,
        y: newTopLeftPoint.y,
        height: newHeight,
        width: newWidth
      })

      this.$emit('changing', this.id, 'bottom-right', this.current, newBottomRightPoint, currentPosition)
    }, THROTTLE_DELAY_TIME, true)

    this.eventRegister(mousemoveHandler, e)
  },
  /**
   * 拖动中左手柄
   * @param e
   */
  dragMiddleLeftHandle (e) {
    let draged = false
    const {rect, viewportRef, sPoint, handlePoint} = getKeyVariable.call(this, 'middle-left')

    const mousemoveHandler = Utils.throttle(e => {
      draged = true
      const currentPosition = Common.getPositionInSvg(viewportRef, e)

      const rotatedCurrentPosition = Common.getRotatedPoint(currentPosition, handlePoint, -rect.rotate)
      const rotatedLeftMiddlePoint = Common.getRotatedPoint({
        x: rotatedCurrentPosition.x,
        y: handlePoint.y
      }, handlePoint, rect.rotate)

      const newWidth = Math.sqrt(Math.pow(rotatedLeftMiddlePoint.x - sPoint.x, 2) + Math.pow(rotatedLeftMiddlePoint.y - sPoint.y, 2), 2)
      const newCenter = {
        x: rotatedLeftMiddlePoint.x - (Math.abs(sPoint.x - rotatedLeftMiddlePoint.x) / 2) * (rotatedLeftMiddlePoint.x > sPoint.x ? 1 : -1),
        y: rotatedLeftMiddlePoint.y + (Math.abs(sPoint.y - rotatedLeftMiddlePoint.y) / 2) * (rotatedLeftMiddlePoint.y > sPoint.y ? -1 : 1)
      }

      if (newWidth < MINIMUM_SIZE) {
        return
      }

      if (!pointInRect(newCenter, handlePoint, sPoint)) {
        return
      }

      Object.assign(this.current, {
        width: newWidth,
        y: newCenter.y - (rect.height / 2),
        x: newCenter.x - (newWidth / 2)
      })

      this.$emit('changing', this.id, 'middle-left', this.current, rotatedLeftMiddlePoint, currentPosition)
    }, THROTTLE_DELAY_TIME, true)

    this.eventRegister(mousemoveHandler, e)
  },
  /**
   * 拖动中右手柄
   * @param e
   */
  dragMiddleRightHandle (e) {
    let draged = false
    const {rect, viewportRef, sPoint, handlePoint} = getKeyVariable.call(this, 'middle-right')

    const mousemoveHandler = Utils.throttle(e => {
      draged = true
      const currentPosition = Common.getPositionInSvg(viewportRef, e)

      const rotatedCurrentPosition = Common.getRotatedPoint(currentPosition, handlePoint, -rect.rotate)
      const rotatedRightMiddlePoint = Common.getRotatedPoint({
        x: rotatedCurrentPosition.x,
        y: handlePoint.y
      }, handlePoint, rect.rotate)

      const newWidth = Math.sqrt(Math.pow(rotatedRightMiddlePoint.x - sPoint.x, 2) + Math.pow(rotatedRightMiddlePoint.y - sPoint.y, 2), 2)
      const newCenter = {
        x: rotatedRightMiddlePoint.x - (Math.abs(sPoint.x - rotatedRightMiddlePoint.x) / 2) * (rotatedRightMiddlePoint.x > sPoint.x ? 1 : -1),
        y: rotatedRightMiddlePoint.y + (Math.abs(sPoint.y - rotatedRightMiddlePoint.y) / 2) * (rotatedRightMiddlePoint.y > sPoint.y ? -1 : 1)
      }

      if (newWidth < MINIMUM_SIZE) {
        return
      }

      if (!pointInRect(newCenter, handlePoint, sPoint)) {
        return
      }

      Object.assign(this.current, {
        width: newWidth,
        y: newCenter.y - (rect.height / 2),
        x: newCenter.x - (newWidth / 2)
      })

      this.$emit('changing', this.id, 'middle-right', this.current, rotatedRightMiddlePoint, currentPosition)
    }, THROTTLE_DELAY_TIME, true)

    this.eventRegister(mousemoveHandler, e)
  }
}

const ResizeHandler = {
  name: 'resize-handler',
  props: {
    id: String,               // 编号
    size: {                   // 定位、宽高
      type: Object,
      default: resetSize
    },
    corrected: {              // 修正值
      type: Object,
      default: resetSize
    },
    getViewportRef: Function, // 获取svg dom引用的方法
    scaling: {  // 缩放比值，用于控制手柄图形的大小
      type: Number,
      default: 100
    },
    selected: Boolean         // 选中态
  },
  data () {
    return {
      current: {
        x: this.size.x,
        y: this.size.y,
        width: this.size.width,
        height: this.size.height,
        rotate: this.size.rotate
      },
      staticValue: {
        negativeThirty: Common.absoluteZoom(staticValueDefault.negativeThirty, this.scaling),
        four: Common.absoluteZoom(staticValueDefault.four, this.scaling),
        two: Common.absoluteZoom(staticValueDefault.two, this.scaling),
        lineWidth: Common.absoluteZoom(staticValueDefault.lineWidth, this.scaling),
        rotate: Common.absoluteZoom(staticValueDefault.rotate, this.scaling),
      },
      cursorStyle: {
        middleLeft: 'ew-resize',
        middleRight: 'ew-resize',
        topMiddle: 'ns-resize',
        bottomMiddle: 'ns-resize',
        topRight: 'nesw-resize',
        bottomLeft: 'nesw-resize',
        topLeft: 'nwse-resize',
        bottomRight: 'nwse-resize',
      }
    }
  },
  computed: {
    correctedSize () {
      const correctedSize = {
        x: this.current.x + this.corrected.x,
        y: this.current.y + this.corrected.y,
        width: this.current.width + this.corrected.width,
        height: this.current.height + this.corrected.height,
        rotate: this.current.rotate
      }

      if (correctedSize.width < MINIMUM_SIZE || (correctedSize.height < MINIMUM_SIZE)) {
        return {
          x: this.current.x,
          y: this.current.y,
          width: this.current.width,
          height: this.current.height,
          rotate: this.current.rotate
        }
      }

      return correctedSize
    },
  },
  watch: {
    size: {
      handler (size, oldVal) {
        this.current = size
      },
      deep: true
    },
    [`current.rotate`]: {
      handler (rotate, oldVal) {
        let that = this
        const horizontal = 'ew-resize' //横
        const vertical = 'ns-resize' //竖
        const oblique = 'nesw-resize' //斜
        const reverseSkew = 'nwse-resize' //反斜
        switch (true) {
          case ((rotate > 22.5 && rotate < 67.5) || (rotate > 202.5 && rotate < 247.5))://第一象限 或 第三象限
            that.cursorStyle.middleLeft = reverseSkew
            that.cursorStyle.middleRight = reverseSkew
            that.cursorStyle.topMiddle = oblique
            that.cursorStyle.bottomMiddle = oblique
            that.cursorStyle.topRight = horizontal
            that.cursorStyle.bottomLeft = horizontal
            that.cursorStyle.topLeft = vertical
            that.cursorStyle.bottomRight = vertical
            break
          case ((rotate > 67.5 && rotate < 112.5) || (rotate > 247.5 && rotate < 292.5))://第一象限 - 第二象限 或 第三象限 - 第四象限
            that.cursorStyle.middleLeft = vertical
            that.cursorStyle.middleRight = vertical
            that.cursorStyle.topMiddle = horizontal
            that.cursorStyle.bottomMiddle = horizontal
            that.cursorStyle.topRight = reverseSkew
            that.cursorStyle.bottomLeft = reverseSkew
            that.cursorStyle.topLeft = oblique
            that.cursorStyle.bottomRight = oblique
            break
          case ((rotate > 112.5 && rotate < 157.5) || (rotate > 292.5 && rotate < 337.5))://第二象限 或 第四象限
            that.cursorStyle.middleLeft = oblique
            that.cursorStyle.middleRight = oblique
            that.cursorStyle.topMiddle = reverseSkew
            that.cursorStyle.bottomMiddle = reverseSkew
            that.cursorStyle.topRight = vertical
            that.cursorStyle.bottomLeft = vertical
            that.cursorStyle.topLeft = horizontal
            that.cursorStyle.bottomRight = horizontal
            break
          case ((rotate > 157.5 && rotate < 202.5) || rotate > 337.5)://第二象限 - 第三象限 或 第四象限 - 第一象限
            that.cursorStyle.middleLeft = horizontal
            that.cursorStyle.middleRight = horizontal
            that.cursorStyle.topMiddle = vertical
            that.cursorStyle.bottomMiddle = vertical
            that.cursorStyle.topRight = oblique
            that.cursorStyle.bottomLeft = oblique
            that.cursorStyle.topLeft = reverseSkew
            that.cursorStyle.bottomRight = reverseSkew
            break
          default:
            that.cursorStyle.middleLeft = horizontal
            that.cursorStyle.middleRight = horizontal
            that.cursorStyle.topMiddle = vertical
            that.cursorStyle.bottomMiddle = vertical
            that.cursorStyle.topRight = reverseSkew
            that.cursorStyle.bottomLeft = reverseSkew
            that.cursorStyle.topLeft = oblique
            that.cursorStyle.bottomRight = oblique
        }
      },
      deep: true
    },
    scaling (scaling) {
      this.staticValue.negativeThirty = Common.absoluteZoom(staticValueDefault.negativeThirty, scaling)
      this.staticValue.four = Common.absoluteZoom(staticValueDefault.four, scaling)
      this.staticValue.lineWidth = Common.absoluteZoom(staticValueDefault.lineWidth, scaling)
      this.staticValue.rotate = Common.absoluteZoom(staticValueDefault.rotate, scaling)
    }
  },
  render (h) {
    const current = this.correctedSize
    const viewBox = `0 0 ${current.width} ${current.height}`
    return (
      <g
        transform={`rotate(${this.current.rotate},${this.current.x + this.current.width / 2},${this.current.y + this.current.height / 2})`}>
        <rect fill="none" stroke="#000" stroke-width="1" width={current.width} height={current.height} x={current.x}
              y={current.y}/>
        <svg viewBox={viewBox} width={current.width} height={current.height} x={current.x} y={current.y}
             style="overflow:visible">
          <rect width="100%" height="100%" fill="transparent" onMousedown={this.dragElement} stroke="#fff"
                onTouchstart={this.dragElement}/>
          <g stroke="#000" stroke-width="1" fill="#fff">
            <line x1="50%" x2="50%" y1="0" y2={this.staticValue.negativeThirty} stroke="#fff"
                  stroke-dasharray={this.staticValue.two}/>
            {/*旋转手柄*/}
            <g className="cursor-rotate" style="cursor:pointer" onMousedown={this.dragRotateHandle}
               onTouchstart={this.dragRotateHandle}
               transform={`translate(${this.current.width / 2 - this.staticValue.rotate / 2},${this.staticValue.negativeThirty - this.staticValue.rotate / 2})`}>
              <svg className="icon" style="" viewBox="0 0 30 30" version="1.1" width={this.staticValue.rotate}
                   height={this.staticValue.rotate}>
                <circle style="cursor:pointer" cx="50%" cy="50%" r="50%" fill="#fff" stroke="transparent"/>
                <g transform={`translate(5,5)`}>
                  <svg className="icon" style="" viewBox="0 0 1024 1024" version="1.1" width="20" height="20"
                       fill="#000">
                    <path
                      d="M528.007408 96.405688V15.99612A15.984831 15.984831 0 0 0 503.544747 2.427075L247.550391 162.433425a15.99612 15.99612 0 0 0 0 27.138089l255.994356 159.995061a15.917098 15.917098 0 0 0 16.244471 0.428971c5.079925-2.822181 8.229479-8.184324 8.229479-13.998015v-79.596781c191.388998 8.387521 344.001235 166.136126 344.001235 359.59096 0 198.816977-161.169088 360.008643-359.997355 360.008643v31.992239c251.840106-0.011289 455.98536-204.17912 455.98536-455.98536-0.011289-246.489251-195.577114-447.14629-440.000529-455.601544z m376.004763 519.574733c0-210.771734-167.242421-383.139235-376.004763-391.583199a395.963223 395.963223 0 0 0-15.996119-0.406394h-15.99612V307.10969L286.214265 175.991181 496.015169 44.861382V127.991533h15.99612c5.362143 0 10.679131 0.214486 15.996119 0.406394 226.384037 8.466542 407.985713 195.182009 407.985713 423.598016a421.475736 421.475736 0 0 1-71.412457 235.256973 389.788292 389.788292 0 0 0 39.431507-171.272495z"/>
                    <path
                      d="M482.762209 1007.044339a456.064381 456.064381 0 0 0 29.237791 0.925675v-31.992239c-9.09871 0-18.253864-0.293507-27.194532-0.857943l-2.043259 31.924507zM111.284224 690.91496l-30.231198 10.498512a458.344703 458.344703 0 0 0 21.414706 51.352397l28.729799-14.110903a427.09752 427.09752 0 0 1-19.913307-47.740006zM93.74155 620.653952a72.022048 72.022048 0 0 0-21.719502-140.668768 72.022048 72.022048 0 0 0-72.010759 72.010759c0 36.259376 26.844582 66.185779 61.715445 71.197972 2.449653 15.555859 5.531474 31.077852 9.572836 46.261184l30.91981-8.229479a421.374137 421.374137 0 0 1-8.47783-40.571668z m-61.738022-68.658009c0-22.058163 17.949068-40.007232 40.007232-40.007232s40.007232 17.949068 40.007231 40.007232-17.949068 40.007232-40.007231 40.007232-40.007232-17.93778-40.007232-40.007232zM145.918024 766.018829l-27.612214 16.176739a458.10764 458.10764 0 0 0 31.021409 46.227318l25.433491-19.427891a425.471944 425.471944 0 0 1-28.842686-42.976166zM394.890795 992.786683c17.870047 4.741263 36.236799 8.410098 54.60355 10.938772l4.346158-31.710021a422.356256 422.356256 0 0 1-50.754096-10.15985l-8.195612 30.931099zM311.467137 961.629809a453.705038 453.705038 0 0 0 51.431419 21.403418l10.475934-30.231199a425.471944 425.471944 0 0 1-47.819028-19.913306l-14.088325 28.741087zM194.504685 832.994819l-23.94338 21.234086a463.989064 463.989064 0 0 0 39.363775 39.341198l21.211509-23.965958a431.172748 431.172748 0 0 1-36.631904-36.609326zM235.742388 914.7929a457.814133 457.814133 0 0 0 46.261184 31.010121l16.16545-27.623504a424.70431 424.70431 0 0 1-43.021321-28.831397l-19.405313 25.44478z"/>
                  </svg>
                </g>
              </svg>
            </g>
            {/*左中*/}
            {/*<circle title="middle-left" cx="0%" r={this.staticValue.four} cy="50%"/>*/}
            <line x1="0" x2="0" y1="0" y2="100%" title="middle-left"
                  fill="transparent" stroke="transparent" stroke-width={this.staticValue.lineWidth}
                  style={`cursor:${this.cursorStyle.middleLeft};`}
                  onMousedown={this.dragMiddleLeftHandle}
                  onTouchstart={this.dragMiddleLeftHandle}/>
            {/*右中*/}
            {/*<circle style="cursor:ew-resize" onMousedown={this.dragMiddleRightHandle}*/}
            {/*onTouchstart={this.dragMiddleRightHandle} title="middle-right" cx="100%"*/}
            {/*r={this.staticValue.four} cy="50%"/>*/}
            <line x1="100%" x2="100%" y1="0" y2="100%" title="middle-right"
                  fill="transparent" stroke="transparent" stroke-width={this.staticValue.lineWidth}
                  style={`cursor:${this.cursorStyle.middleRight};`}
                  onMousedown={this.dragMiddleRightHandle}
                  onTouchstart={this.dragMiddleRightHandle}/>
            {/*顶部中间*/}
            {/*<circle style="cursor:ns-resize" onMousedown={this.dragTopMiddleHandle}*/}
            {/*onTouchstart={this.dragTopMiddleHandle} title="top-middle" cx="50%"*/}
            {/*r={this.staticValue.four} cy="0"/>*/}
            <line x1="100%" x2="0" y1="0" y2="0" title="top-middle"
                  fill="transparent" stroke="transparent" stroke-width={this.staticValue.lineWidth}
                  style={`cursor:${this.cursorStyle.topMiddle};`}
                  onMousedown={this.dragTopMiddleHandle}
                  onTouchstart={this.dragTopMiddleHandle}/>
            {/*底部中间*/}
            {/*<circle style="cursor:ns-resize" onMousedown={this.dragBottomMiddleHandle}*/}
            {/*onTouchstart={this.dragBottomMiddleHandle} title="bottom-middle" cx="50%"*/}
            {/*r={this.staticValue.four} cy="100%"/>*/}
            <line x1="100%" x2="0" y1="100%" y2="100%" title="bottom-middle"
                  fill="transparent" stroke="transparent" stroke-width={this.staticValue.lineWidth}
                  style={`cursor:${this.cursorStyle.bottomMiddle};`}
                  onMousedown={this.dragBottomMiddleHandle}
                  onTouchstart={this.dragBottomMiddleHandle}/>
            {/*右上方*/}
            <circle style={`cursor:${this.cursorStyle.topRight};`} onMousedown={this.dragTopRightHandle}
                    onTouchstart={this.dragTopRightHandle} title="top-right" cx="100%"
                    r={this.staticValue.four} cy="0" stroke="#fff"/>
            {/*左下方*/}
            <circle style={`cursor:${this.cursorStyle.bottomLeft};`} onMousedown={this.dragBottomLeftHandle}
                    onTouchstart={this.dragBottomLeftHandle} title="bottom-left" cx="0"
                    r={this.staticValue.four} cy="100%" stroke="#fff"/>
            {/*左上方*/}
            <circle style={`cursor:${this.cursorStyle.topLeft};`} onMousedown={this.dragTopLeftHandle}
                    onTouchstart={this.dragTopLeftHandle} title="top-left" cx="0"
                    r={this.staticValue.four} cy="0" stroke="#fff"/>
            {/*左下方*/}
            <circle style={`cursor:${this.cursorStyle.bottomRight};`} onMousedown={this.dragBottomRightHandle}
                    onTouchstart={this.dragBottomRightHandle} title="bottom-right" cx="100%"
                    r={this.staticValue.four} cy="100%" stroke="#fff"/>
          </g>
        </svg>
      </g>
    )
  },
  methods: {
    ...handleMethods
  }
}

export default ResizeHandler
